package p.ithorns.tools.translator.apt.model;

import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.ListBuffer;
import p.ithorns.tools.translator.apt.utils.AptUtil;

import java.util.List;
import java.util.Objects;

/**
 * AnnotateMeta
 * <p>
 * 注解元数据
 *
 * @author HtL
 * @date 2024/6/6 20:57
 * @since 1.0.0
 */
public class AnnotateMeta {
    /**
     * 注解名称
     */
    private String name;

    /**
     * 注解类型全限定名
     */
    private String fqn;

    /**
     * 被注解者(字段/方法/类)名称
     */
    private String ownerName;

    /**
     * 参数列表
     */
    private ListBuffer<JCTree.JCExpression> args;

    private List<AnnotatedParam> params;

    public AnnotateMeta() {
    }

    public AnnotateMeta(String name, String fqn, String ownerName) {
        this(name, fqn, ownerName, new ListBuffer<>());
    }

    public AnnotateMeta(String name, String fqn, String ownerName, ListBuffer<JCTree.JCExpression> args) {
        this.name = name;
        this.fqn = fqn;
        this.ownerName = ownerName;
        this.args = args;
    }

    public AnnotateMeta(JCTree.JCAnnotation annotation, String ownerName) {
        this(AptUtil.getJcAnnotationTypeName(annotation), AptUtil.getJcAnnotationFQN(annotation), ownerName);
        annotation.getArguments().forEach(e -> {
            JCTree.JCAssign jcAssign = (JCTree.JCAssign) e;
            this.args.append(jcAssign);
        });
    }

    public void reset(Class<?> clazz, List<AnnotatedParam> params) {
        setName(clazz.getSimpleName());
        setFqn(clazz.getName());
        setParams(params);
    }

    public String getName() {
        return name;
    }

    public ListBuffer<JCTree.JCExpression> getArgs() {
        return args;
    }

    public String getOwnerName() {
        return ownerName;
    }

    public String getFqn() {
        return fqn;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setFqn(String fqn) {
        this.fqn = fqn;
    }

    public List<AnnotatedParam> getParams() {
        return params;
    }

    public void setParams(List<AnnotatedParam> params) {
        this.params = params;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        AnnotateMeta that = (AnnotateMeta) o;

        if (!Objects.equals(ownerName, that.ownerName)) {
            return false;
        }
        return Objects.equals(fqn, that.fqn);
    }

    @Override
    public int hashCode() {
        int result = ownerName != null ? ownerName.hashCode() : 0;
        result = 31 * result + (fqn != null ? fqn.hashCode() : 0);
        return result;
    }

}